package com.lf.api.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.core.RedisTemplate;

import com.lf.api.Constants;
import com.lf.api.util.AESUtil;
import com.lf.api.util.HttpUtil;
import com.lf.api.util.IFConfig;
import com.lf.api.util.SpringContextUtil;
import com.lf.api.vo.MessageResult;

/**
 * Servlet Filter implementation class LoginFilter
 */
@WebFilter("/LoginFilter")
public class LoginFilter implements Filter {

    /**
     * Default constructor. 
     */
    public LoginFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		if(IFConfig.getValue("checkLogin", 0) == Constants.NOT_CHECK_LOGIN
				|| httpRequest.getRequestURI().contains("/login") 
				|| httpRequest.getRequestURI().contains("/toLogin")){
			chain.doFilter(request, response);
		}else{
			String username = httpRequest.getParameter("username");
			String sign = httpRequest.getParameter("sign");
			String timestamp = httpRequest.getParameter("timestamp");
			if(StringUtils.isEmpty(sign) || StringUtils.isEmpty(timestamp)
					|| StringUtils.isEmpty(username) || !NumberUtils.isNumber(timestamp)){
				HttpUtil.write(httpResponse, MessageResult.SYSTEM_ERROR.setMsg("param sign or timestamp is empty!"));
				return;
			}
			if(Math.abs(System.currentTimeMillis() - Long.valueOf(timestamp)) > 30){
				HttpUtil.write(httpResponse, MessageResult.SYSTEM_ERROR.setMsg("request is over 30s!"));
				return;
			}
			RedisTemplate<String, String> redisTemplate = SpringContextUtil.getBean("redisTemplate");
			if(null == redisTemplate.opsForValue().get(username)){
				HttpUtil.write(httpResponse, MessageResult.SYSTEM_ERROR.setMsg("not login!"));
				return;
			}
			String requestUrl = httpRequest.getRequestURL().substring(0, httpRequest.getRequestURL().lastIndexOf("?"));
			String token = redisTemplate.opsForValue().get(username);
			requestUrl = requestUrl + "?username=" + username + "&token=" + token + "&timestamp=" + timestamp;
			try {
				if(!AESUtil.md5(requestUrl).equals(sign)){
					HttpUtil.write(httpResponse, MessageResult.SYSTEM_ERROR.setMsg("login valid error!"));
					return;
				}
			} catch (Exception e) {
				e.printStackTrace();
				HttpUtil.write(httpResponse, MessageResult.SYSTEM_ERROR.setMsg(e.getMessage()));
				return;
			}
			chain.doFilter(request, response);
		}
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}
